home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / w3dvb5 / supernas.bas < prev    next >
BASIC Source File  |  1997-12-22  |  21KB  |  909 lines

  1. Attribute VB_Name = "SUPERNAS1"
  2. ' Modulo per l'algoritmo del Pittore.
  3. ' Routine di entrata: Pittore
  4.  
  5.  
  6. Type Vec_Int
  7.    x As Integer
  8.    Y As Integer
  9. End Type
  10.  
  11. Type Vertex
  12.    x As Integer
  13.    Y As Integer
  14.    Z As Integer
  15.    Used As Integer
  16. End Type
  17. Public v() As Vertex
  18.  
  19.  
  20. Type triadata
  21.    Normal As Vec3
  22.    h As Single
  23.    Color As Integer
  24. End Type
  25.  
  26.  
  27. Type Tria
  28.     Anr As Integer
  29.     Bnr As Integer
  30.     Cnr As Integer
  31.     Z As Integer
  32.     PTria As triadata ' Valore Triadata
  33. End Type
  34.  
  35. Public Triangles() As Tria
  36. Public Ptriangles As Integer
  37.  
  38. Type TriaNode
  39.     trnr As Integer
  40.     NextNodo As Integer
  41. End Type
  42.  
  43.  
  44. Public Const LARGE = 32000 ' // Non maggiore di sqrt(LONG_MAX)
  45. Public Const LARGE1 = 32001 ' Usato solo da LineaNas
  46. Public Const PIdiv180 = 0.0174532
  47. Public Const BIG = 1E+30
  48.  
  49. Public X__max As Integer ' Coordinate reali della finestra
  50. Public Y__max As Integer ' Coordinate reali della finestra
  51.  
  52. Public f As Double
  53. Public zfactor As Double
  54. Public rcolormin As Double
  55. Public rcolormax As Double
  56. Public delta As Double
  57. Public zemin As Double
  58. Public zemax As Double
  59. Public xsC As Double
  60. Public ysC As Double
  61. Public XLCreal As Double
  62. Public YLCreal As Double
  63.  
  64. Public kEye As Integer
  65. Public hK As Integer
  66. Public XLC As Integer
  67. Public YLC As Integer
  68.  
  69.  
  70. Public Vt() As Vec3
  71. Public lightvector As Vec3
  72.  
  73.  
  74.  
  75. Public TriaNodeNext() As TriaNode
  76.  
  77. Public PStart As Integer
  78. Public PEnd As Integer
  79.  
  80.  
  81. Sub Complete_Triangles(n As Integer, offset As Integer, nrs_tr() As Trianrs)
  82.  
  83. '// Completa triangles[offset],..., triangles[offset+n-1].
  84. '// Numeri di vertice: nrs_tr[0],..., nrs_tr[n-1].
  85. '// Questi triangoli appartengono allo stesso poligono. L'equazione
  86. '// del loro piano Φ nx . x + ny . y + nz . z = h.
  87.   
  88.   
  89.   Dim i As Integer
  90.   Dim Anr As Integer
  91.   Dim Bnr As Integer
  92.   Dim Cnr As Integer
  93.   Dim ZA As Integer
  94.   Dim ZB As Integer
  95.   Dim ZC As Integer
  96.   Dim zmin As Single
  97.   Dim zmax As Single
  98.  
  99.   Dim nx As Double
  100.   Dim ny As Double
  101.   Dim nz As Double
  102.   Dim ux As Double
  103.   Dim uy As Double
  104.   Dim uz As Double
  105.   Dim vx As Double
  106.   Dim vy As Double
  107.   Dim vz As Double
  108.   Dim factor As Double
  109.   Dim h As Double
  110.   Dim Ax As Double
  111.   Dim Ay As Double
  112.   Dim Az As Double
  113.   Dim Bx As Double
  114.   Dim By As Double
  115.   Dim Bz As Double
  116.   Dim Cx As Double
  117.   Dim Cy As Double
  118.   Dim Cz As Double
  119.   
  120.   Dim p As Integer
  121.   Dim q As triadata
  122.   
  123. '   // Se il poligono Φ un'approssimazione di una circonferenza, i
  124. '   // primi tre vertici possono giacere quasi sulla stessa linea,
  125. '   // da cui n/2 invece di 0 nell'istruzione for che segue:
  126.   
  127.   For i = n \ 2 To n
  128.      Anr = nrs_tr(i).a
  129.      Bnr = nrs_tr(i).b
  130.      Cnr = nrs_tr(i).C
  131.      If (orienta(Anr, Bnr, Cnr) > 0) Then Exit For
  132.    Next
  133.  
  134.    ZA = v(Anr).Z
  135.    ZB = v(Bnr).Z
  136.    ZC = v(Cnr).Z
  137.  
  138.    Az = zEye(ZA)
  139.    Bz = zEye(ZB)
  140.    Cz = zEye(ZC)
  141.    Ax = xScreen(v(Anr).x) * Az
  142.    Ay = yScreen(v(Anr).Y) * Az
  143.    Bx = xScreen(v(Bnr).x) * Bz
  144.    By = yScreen(v(Bnr).Y) * Bz
  145.    Cx = xScreen(v(Cnr).x) * Cz
  146.    Cy = yScreen(v(Cnr).Y) * Cz
  147.    ux = Bx - Ax
  148.    uy = By - Ay
  149.    uz = Bz - Az
  150.    vx = Cx - Ax
  151.    vy = Cy - Ay
  152.    vz = Cz - Az
  153.    nx = uy * vz - uz * vy
  154.    ny = uz * vx - ux * vz
  155.    nz = ux * vy - uy * vx
  156.    h = nx * Ax + ny * Ay + nz * Az
  157.    factor = 1 / Sqr(nx * nx + ny * ny + nz * nz)
  158.    q.Normal.x = nx * factor
  159.    q.Normal.Y = ny * factor
  160.    q.Normal.Z = nz * factor
  161.    q.h = h * factor
  162.    For i = 0 To n - 1
  163.       p = offset + i
  164.       Triangles(p).Anr = nrs_tr(i).a
  165.       Triangles(p).Bnr = nrs_tr(i).b
  166.       Triangles(p).Cnr = nrs_tr(i).C
  167.       Triangles(p).PTria = q
  168.    '   // Sceglie il lato del triangolo per cui Z varia maggiormente;
  169.    '   // Triangles(p).Z si baserα sul punto medio di questo lato:
  170.       zmin = v(Triangles(p).Anr).Z
  171.       zmax = zmin
  172.       ZB = v(Triangles(p).Bnr).Z
  173.       ZC = v(Triangles(p).Cnr).Z
  174.       If (ZB < zmin) Then
  175.          zmin = ZB
  176.       ElseIf (ZB > zmax) Then
  177.          zmax = ZB
  178.       End If
  179.       If (ZC < zmin) Then
  180.          zmin = ZC
  181.       ElseIf (ZC > zmax) Then
  182.          zmax = ZC
  183.       End If
  184.       Triangles(p).Z = (zmin + zmax) / 2
  185.   
  186.    Next
  187.  
  188. End Sub
  189.  
  190. Sub DeleteList(Start() As TriaNode)
  191.  
  192.    Dim p As TriaNode
  193. '   Do While (Start <> Null)
  194. '     p = start;
  195. '     start = start->next;
  196.  
  197. End Sub
  198.  
  199. Function Distance(ITria As Integer, x As Integer, Y As Integer) As Double
  200.  
  201.  
  202. '// Si considera la linea passante per il punto di osservazione E
  203. '// e il punto (X, Y) del video. Interessa il punto in cui questa
  204. '// linea interseca il triangolo itria. Sarα restituita la
  205. '// coordinata ze di questo punto.
  206.  
  207.   Static Dist0 As Double
  208.   Static X0 As Integer
  209.   Static Y0 As Integer
  210.   Static PTria0 As Integer
  211.    
  212.   Dim a As Double
  213.   Dim b As Double
  214.   Dim C As Double
  215.   Dim h As Double
  216.   Dim xs As Double
  217.   Dim ys As Double
  218.   
  219. '  Dist0 = 0: X0 = 0: Y0 = 0
  220.    
  221.  ' // Variabili statiche, qualora lo stesso punto (X, Y) sia usato
  222.  ' // per due triangoli consecutivi appartenenti allo stesso
  223.  ' // poligono (e quindi con lo stesso puntatore ptria).
  224.   
  225.   Dim TriaPtr As Integer
  226.   Dim PTria As Integer
  227.   
  228.   TriaPtr = ITria
  229. '  PTria = Triangles(TriaPtr).PTria
  230.   
  231.  '  tria huge* triaptr = triangles + itria; // = &triangles[itria]
  232.  '  triadata huge*ptria=triaptr->ptria;
  233.    
  234.    If (PTria0 <> TriaPtr Or x <> X0 Or Y <> Y0) Then
  235.       a = Triangles(TriaPtr).PTria.Normal.x
  236.       b = Triangles(TriaPtr).PTria.Normal.Y
  237.       C = Triangles(TriaPtr).PTria.Normal.Z
  238.       h = Triangles(TriaPtr).PTria.h
  239.       xs = xScreen(x)
  240.       ys = yScreen(Y)
  241.       Dist0 = h * Sqr(xs * xs + ys * ys + 1) / (a * xs + b * ys + C)
  242.       X0 = x
  243.       Y0 = Y
  244.       PTria0 = TriaPtr
  245.    End If
  246.    
  247.    Distance = Dist0
  248.  
  249. End Function
  250.  
  251.  
  252.  
  253. Sub DrawWireFrame(Pic As PictureBox)
  254.  
  255. Dim i As Integer, k As Integer, j As Integer
  256.   
  257. For k = 1 To UBound(FileVertex)
  258.  i = Abs(FileVertex(k).Vert(1))
  259.  If i > 0 Then
  260.     Xl = to_pix(v(i).x)
  261.     Yl = to_pix(v(i).Y)
  262.     x1 = Xl
  263.     y1 = Yl
  264.     For j = 1 To FileVertex(k).Count
  265.         i = FileVertex(k).Vert(j)
  266.         If i > 0 Then
  267.            x = to_pix(v(i).x)
  268.            Y = to_pix(v(i).Y)
  269.            Pic.Line (x1, y1)-(x, Y)
  270.            x1 = x: y1 = Y
  271.         End If
  272.     Next j
  273.  End If
  274.           
  275. Next
  276.  
  277.    
  278. End Sub
  279.  
  280. Sub Fill_Triangle(Pic As PictureBox, i As Integer)
  281.  
  282. ' // Riempie il triangolo i
  283.  
  284.  Dim Triangle(2) As CornerRec
  285.  Dim Anr As Integer
  286.  Dim Bnr As Integer
  287.  Dim Cnr As Integer
  288.  
  289.  Anr = Triangles(i).Anr
  290.  Bnr = Triangles(i).Bnr
  291.  Cnr = Triangles(i).Cnr
  292.  
  293.  Triangle(0).x = to_pix(v(Anr).x)
  294.  Triangle(0).Y = to_pix(v(Anr).Y)
  295.  
  296.  Triangle(1).x = to_pix(v(Bnr).x)
  297.  Triangle(1).Y = to_pix(v(Bnr).Y)
  298.  
  299.  Triangle(2).x = to_pix(v(Cnr).x)
  300.  Triangle(2).Y = to_pix(v(Cnr).Y)
  301.  
  302.  Shade% = Triangles(i).PTria.Color
  303.  
  304.  Call DrawTriangle(Pic, Triangle(), Shade%)
  305.  
  306. End Sub
  307.  
  308. Sub FindRange(i As Integer)
  309.    Dim Normal As Vec3
  310.    Normal.x = Triangles(i).PTria.Normal.x
  311.    Normal.Y = Triangles(i).PTria.Normal.Y
  312.    Normal.Z = Triangles(i).PTria.Normal.Z
  313.    Dim rcolor As Single
  314.    rcolor = DotProduct(Normal, lightvector)
  315.    If (rcolor < rcolormin) Then rcolormin = rcolor
  316.    If (rcolor > rcolormax) Then rcolormax = rcolor
  317. End Sub
  318.  
  319.  
  320. Function Inside_Triangle(x As Integer, Y As Integer, XA As Integer, YA As Integer, XB As Integer, YB As Integer, xC As Integer, yC As Integer) As Integer
  321.  
  322.  
  323. '  // (X, Y) giace sopra o dentro il triangolo ABC?
  324.    
  325.  Inside_Triangle = Orientation(XB - XA, YB - YA, x - XA, Y - YA) >= 0 And _
  326.                   Orientation(xC - XB, yC - YB, x - XB, Y - YB) >= 0 And _
  327.                   Orientation(XA - xC, YA - yC, x - xC, Y - yC) >= 0
  328.    
  329. End Function
  330.  
  331.  
  332. Function Int_To_Pix(x As Double)
  333.   Int_To_Pix = (x + hK) / k
  334. End Function
  335.  
  336. Function IntersectOrizontal(a As Vec_Int, b As Vec_Int, Y As Integer, xxMin As Integer, xxmax As Integer) As Integer
  337.  
  338.  
  339. ' // Il segmento AB ha dei punti in comune con il
  340. ' // segmento orizzontale {(Xmin, Y), (Xmax, Y)}?
  341.  
  342.  
  343. Dim XA As Integer
  344. Dim YA As Integer
  345. Dim XB As Integer
  346. Dim YB As Integer
  347. Dim dx As Long
  348. Dim dy As Long
  349. Dim yDx As Long